/****************************************************************************
**
****************************************************************************/

#ifndef BASEUPDATE_H
#define BASEUPDATE_H

#include <QThread>
#include <QNetworkReply>

class QSettings;
class QFile;
class QNetworkAccessManager;

class BaseUpdate : public QObject
{
    Q_OBJECT

public:
    ///
    /// \brief The State enum
    ///
    enum State {
        kInvalid = 0, /* ... */
        kUpdateing,   /* ... */
        kSuccess,     /* ... */
        kFailed,      /* ... */
    };

    explicit BaseUpdate(QObject *parent = nullptr);
    ~BaseUpdate();

    static qint32 version()
    {
        return version_;
    }
    static qint32 subversion()
    {
        return subversion_;
    }
    static qint32 revision()
    {
        return revision_;
    }

    static double progress()
    {
        return progress_;
    }
    static void set_progress(double progress)
    {
        progress_ = progress;
    }
    static State state()
    {
        return state_;
    }
    static void set_state(const State& state)
    {
        state_ = state;
    }

protected:

private:
    struct DownloadInfo {
        qint32 version;
        qint32 subversion;
        qint32 revision;
        qint32 packLength;
        qint32 checkSum;
        QString updateType;
    };

    bool m_quit;
    QUrl *m_otaUrl = nullptr;
    QFile *m_otaFile = nullptr;
    QNetworkReply *m_downloadReply = nullptr;
    QNetworkAccessManager *m_otaManager = nullptr;
    struct DownloadInfo m_downloadInfo;

    static qint32 version_;
    static qint32 subversion_;
    static qint32 revision_;
    static double progress_;
    static State state_;

private:
    void InitializationVersion(qint32 version, qint32 subversion, qint32 revision);
    void ConfigureVersion(qint32 version, qint32 subversion, qint32 revision);

    bool CheckUrl();
    bool CheckSavePath();

    void SetNamePassword(const QString name, const QString password);
    void SetUrl(const QString url);
    void CreateDownloadFile(const QString name);

    quint16 CheckCRC();

signals:
    void DownloadFinish(qint32 subversion, qint32 revision, qint32 packLength, qint32 checkSum, QString updateType);

public slots:
    void StartDownloadFile(qint32 version, qint32 subversion, qint32 revision, qint32 packLength, qint32 checkSum, QString updateAddress);

private slots:
    void DownloadReadyRead();
    void DownloadError(QNetworkReply::NetworkError code);
    void DownloadReplyFinished(QNetworkReply *reply);
};

#endif // BASEUPDATE_H
